package com.ljs.module.util;

import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ljs.module.common.PathEnum;
import com.ljs.module.entity.template.upgrade.ConversionValueType;
import com.ljs.module.entity.template.upgrade.Upgrade;
import org.apache.commons.lang3.StringUtils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 构建升级类
 * Created by lijunsai on 2021/07/28
 */
public class UpgradeUtil {
    public static String valueTypeFilePath = PathEnum.CONFIG.getPath() + File.separator + "valueType.txt";
    public static String basicDir = "";
    public static String packageName = "";
    public static Map<String, String> modulePathMap = new HashMap<>();
    public static Map<String, ConversionValueType> fieldClass = new HashMap<>();

    static {
        ObjectMapper objectMapper = new ObjectMapper();
        FileUtil.fileNotExistThenMake(valueTypeFilePath);
        String content = FileUtil.readFile2Content(valueTypeFilePath);
        if (!StringUtils.isBlank(content)) {
            JavaType javaType = objectMapper.getTypeFactory().constructParametricType(ArrayList.class, ConversionValueType.class);
            List<ConversionValueType> data = null;
            try {
                data = objectMapper.readValue(content, javaType);
                fieldClass = data.stream().collect(Collectors.toMap(x -> x.getValueType(), y -> y, (v1,v2)->v1));
            } catch (IOException e) {
            }
        }
    }

    /**
     * 通过扩展包路径 找到application中Module的路径  等到包路径
     * @param projectPath 扩展包路径
     */
    public static void init(final String projectPath) throws Exception {
        reset();
        List<String> modulePaths = FileUtil.findModulePath(projectPath);
        if (modulePaths == null || modulePaths.size() == 0) {
            throw new Exception("在application中没有找到有注册Module的Bean");
        }
        modulePathMap = modulePaths.stream().collect(Collectors.toMap(k -> k.substring(k.lastIndexOf(".") + 1), v -> v.substring(0, v.lastIndexOf(".")), (v1,v2)->v1));
        // 如果有多个  默认先选第一个
        String modulePath = modulePaths.get(0);
        changeModule(projectPath, modulePath.substring(modulePath.lastIndexOf(".") + 1));
    }

    public static void changeModule(String projectPath, String moduleName) throws Exception {
        packageName = modulePathMap.get(moduleName);
        basicDir = projectPath + File.separator + "src" + File.separator + "java"+ File.separator + packageName.replaceAll("\\.", Util.getNowFileSepartor());
    }

    /**
     * 重置当前状态
     */
    public static void reset(){
        modulePathMap.clear();
        basicDir = "";
        packageName = "";
    }

    public static String insertPojoToModule(Upgrade build){
        String moduleName = basicDir + File.separator + build.getModule() + ".java";
        File file = new File(moduleName);
        if (!file.exists()) {
            return "Module不存在";
        }
        BufferedReader reader = null;
        FileOutputStream fos = null;
        StringBuilder packageCode = new StringBuilder();
        StringBuilder importCode = new StringBuilder();
        StringBuilder beforeActive = new StringBuilder();
        StringBuilder afterActive = new StringBuilder();
        try {
            reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));
            String classToActive = "DAOModule.getInstance().addPOJOClass(" + build.getEntityName() + ".class);";
            String packageName = UpgradeUtil.packageName + ".entity." + build.getEntityName();
            boolean after = false;
            boolean before = false;
            boolean imporT = false;
            String temp = "";
            while ((temp = reader.readLine()) != null) {
                if (after) {
                    afterActive.append(temp + "\r\n");
                } else if (before) {
                    beforeActive.append(temp + "\r\n");
                    if (temp.contains("public void activate()")) {
                        after = true;
//                        afterActive.append(temp + "\r\n");
                        continue;
                    }
                } else if (imporT) {
                    if (temp.contains("public class")) {
                        before = true;
                        beforeActive.append(temp + "\r\n");
                        continue;
                    }
                    importCode.append(temp + "\r\n");
                } else {
                    if (temp.contains("import ")) {
                        imporT = true;
                        importCode.append(temp + "\r\n");
                        continue;
                    }
                    packageCode.append(temp + "\r\n");
                }
            }
            if (!importCode.toString().contains(packageName)) {
                packageCode.append("import " + packageName + ";\r\n");
            }
            if (!importCode.toString().contains("import smartbi.repository.DAOModule;")) {
                packageCode.append("import smartbi.repository.DAOModule;\r\n");
            }
            packageCode.append(importCode).append(beforeActive);
            if (!afterActive.toString().contains(classToActive)) {
                packageCode.append("        " + classToActive + "\r\n");
            }
            packageCode.append(afterActive);
            fos = new FileOutputStream(file);
            fos.write(packageCode.toString().getBytes("UTF-8"));
            fos.flush();
        } catch (Exception e) {

        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return "";
    }
}
